import { Canvas, error, find, instantiate, Node, Prefab, resources } from "cc";
import { UIBase } from "./UIBase";

/**
 * UI管理单例
 */
export default class UIManager
{
    public static readonly  UI_PREFABS_PATH : string = "prefabs/UI/";

    public static readonly UI_LAYER = {
        UIRoot : "UIRoot",
        UIPage : "UIPage",
        UIWidget : "UIWidget",
        UIWindow : "UIWindow"
    };


    public static get Instance() : UIManager {
        if(!this._Instance)
            this._Instance = new UIManager();
        return this._Instance; 
    }
    private static _Instance : UIManager;

    private constructor(){
        
    }

//#region 临时变量
    
//#endregion

    /**
     * ui map
     */
    private UIs : Map<string,UIBase> = new Map();

    /**
     * 存储ui层
     */
    private Layers : Map<string,Node> = new Map();

    /**
     * 初始化UIManager
     */
    public Init(){
        var canvas = find("Canvas");
        let root = new Node(UIManager.UI_LAYER.UIRoot);
        let page = new Node(UIManager.UI_LAYER.UIPage);
        let widget = new Node(UIManager.UI_LAYER.UIWidget);
        let window = new Node(UIManager.UI_LAYER.UIWindow);
        canvas.addChild(root);
        root.addChild(page);
        root.addChild(widget);
        root.addChild(window);
        this.Layers.set(UIManager.UI_LAYER.UIRoot,root);
        this.Layers.set(UIManager.UI_LAYER.UIPage,page);
        this.Layers.set(UIManager.UI_LAYER.UIWidget,widget);
        this.Layers.set(UIManager.UI_LAYER.UIWindow,window);
    }

    /**
     * 打开UI
     * @param key UI的key
     * @param layer UI所属层级
     */
    public async OpenUI<T extends UIBase>(key:string,layer:string) : Promise<T>{
        //  从对象池获取UI
        var pre_open_ui = this.UIs.get(key);
        //  如果没有，尝试加载
        if(!pre_open_ui){
            let uibaseComp = await this.loadUI<T>(key);
            let node = uibaseComp.node;
            this.UIs.set(uibaseComp.UIName,uibaseComp);
            //  向Layer载入ui
            let layerNode = this.Layers.get(layer);
            layerNode.addChild(node);
            layerNode.active = true;
            uibaseComp.onOpen();
            return uibaseComp;
        }else{
            pre_open_ui.node.active = true;
            pre_open_ui.onOpen();
            return pre_open_ui as T;
        }
    }

    private loadUI<T extends UIBase>(key:string) : Promise<T>{
        var path = UIManager.UI_PREFABS_PATH + key;
        return new Promise<T>(
            (resolve, reject)=>{
                resources.load(path,Prefab,
                    (err,prefab)=>{
                        if(err)
                        {
                            reject("UIManager: Failed Load UI "+key);
                        }
                        let node = instantiate(prefab)
                        let uibaseComp = node.getComponent(UIBase);
                        if(!uibaseComp){
                            uibaseComp = node.addComponent(UIBase);
                        }
                        resolve(uibaseComp as T);
                });
            }
        );
    } 

    /**
     * 关闭UI
     * @param key UI的key
     */
    public CloseUI(key:string){
        var pre_close_ui = this.UIs.get(key);
        if(!pre_close_ui){
            console.error("UIManager: UI "+key+" Not Found");
            return;
        }
        pre_close_ui.onClose();
        pre_close_ui.node.active = false;
    }

    /**
     * 移除UI
     * @param key UI的key
     */
    public RemoveUI(key:string){
        var pre_remove_ui = this.UIs.get(key);
        if(!pre_remove_ui){
            console.error("UIManager: UI "+key+" Not Found");
            return;
        }
        this.UIs.delete(key);
        pre_remove_ui.destroy();
    }

}